package main

import (
	"encoding/json"
	"io"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)
func init(){
	f,err:=os.OpenFile("log.log",os.O_CREATE|os.O_APPEND|os.O_RDWR,os.ModePerm)
	if err !=nil{
		panic(err)
	}
	multiWriter:=io.MultiWriter(os.Stdout,f)
	log.SetOutput(multiWriter)
	log.SetPrefix("[log]")
	log.SetFlags(log.LstdFlags|log.Lshortfile|log.Ldate)

	return
}


type PersistedQuery struct{
	Version int	`json:"version"`
	Sha256Hash string	`json:"sha256Hash"`
}
type Extensions struct {
	PersistedQuery PersistedQuery `json:"persistedQuery"`
}
type Location struct {
	Latitude  interface{} `json:"latitude"`
	Longitude interface{} `json:"longitude"`
	Address   string      `json:"address"`
}
type EntryAttributes struct {
	Field1  string `json:"field_1"`
	Field2  string `json:"field_2"`
	Field3  string `json:"field_3"`
	Field6  string `json:"field_6"`
	Field4  string `json:"field_4"`
	Field7  string `json:"field_7"`
	Field16 Location `json:"field_16"`
	Field21 []string `json:"field_21"`
}
type Input struct {
	FormId string `json:"formId"`
	EntryAttributes EntryAttributes `json:"entryAttributes"`
	CaptchaData interface{} `json:"captchaData"`
	weixinAccessToken interface{}
	xFieldWeixinOpenid interface{}
	weixinInfo interface{}
	prefilledParams string
	embedded bool
	internal bool
	backgroundImage bool
	formMargin bool
	hasPreferential bool
	fillingDuration float64
	forceSubmit bool
}
type Variables struct {
	Input Input `json:"input"`
}
type PostData struct {
	OperationName string `json:"operationName"`
	Variables Variables `json:"variables"`
	Extensions Extensions `json:"extensions"`
}
func main() {

	// 2019-06-26 22:06:00 +0800 CST
	var config Config
	config.GetConf()
	name:=config.UserName
	number:=config.SchoolNumber

	//填表花了多长时间
	fillTime:=21.002 + (35.120-21.002)*rand.Float64()
	persistedQuery:=PersistedQuery{Version: 1,Sha256Hash:"0f9106976e7cf5f19e8878877bc8030cddcb7463dd76f4e02bc5c67b5874eeae"}
	extensions:=Extensions{PersistedQuery: persistedQuery}
	location:=Location{Address: "成都市"}
	entryAttributes:=EntryAttributes{Field1:name,Field2: number,Field3: "KsBW",Field6: "JsBh",Field4: "zBCK",
									Field7: "GaXt",Field16: location,Field21: []string{"srmW"}}
	input:=Input{FormId: "kDiOo6",EntryAttributes: entryAttributes,prefilledParams: "",embedded: false,internal: false,backgroundImage: false,
		formMargin: false,hasPreferential: false,forceSubmit: false,fillingDuration:fillTime}
	v:=Variables{Input: input}
	postData:=PostData{OperationName: "CreatePublishedFormEntry",Variables: v,Extensions: extensions}
	b, err := json.Marshal(postData)
	if err != nil {
		log.Fatal(err)
	}
	var data = strings.NewReader(string(b))
	//当前填表时间
	t:=time.Now()
	//表格当天时间中午12点多 这个时间？ 不晓得啥用
	//timeNow :=" 12:24:23"
	tt:=time.Date(t.Year(),t.Month(),t.Day(),12,24,23,0,t.Location())

	client := &http.Client{}
	req, err := http.NewRequest("POST", "https://jinshuju.net/graphql/f/kDiOo6", data)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("authority", "jinshuju.net")
	req.Header.Set("accept", "*/*")
	req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
	req.Header.Set("content-type", "application/json;charset=UTF-8")
	//有几个时间戳不知道干什么用的，能记录填表时长
	//req.Header.Set("cookie", "_ga=GA1.2.1084946596.1625314918; jsj_uid=bbb0a6ef-d2ad-4f91-b46b-eb817318130e; my_forms_has_data=true; _caid=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqWXlPR0kwTlRJMU1XUmpZelF5TWpZeU1XRTRNelJqTmlJPSIsImV4cCI6IjIwMjMtMDUtMjNUMDk6Mjk6NTUuMTI1WiIsInB1ciI6bnVsbH19--2967b6faa753973508892c42b77e9541aa34bbf8; start_filling_time_GBXkNY=1653539063; Hm_lvt_47cd03e974df6869353431fe4f4d6b2f=1653303538,1653321358,1653539063,1653560134; filled_form_scene=form; last_fill_entry_token=WqyKnPTY; referer_url=https%3A%2F%2Fjinshuju.net%2Ff%2FkDiOo6; locale=zh-CN; start_filling_time_kDiOo6=1653562435; csrf_token=9utCeK8yw6FzyM8Q6pBnhvFBUqB1pBgn8JGYVgrqNaHYjEGsMpHAaXGHkkVP3CpYSzcf87esicMEYlCi3TYTWg==; Hm_lpvt_47cd03e974df6869353431fe4f4d6b2f=1653562434; _gd_session=emZ5OHdqSnY0cEl0NTJqNU5kUjlqS2o1cHNLZ1ZIUHVjSyswRWJLdW5oZHZzSEZWQ0hydGVVWnZjZlE1R2laWXJkV2lKTHJDbVB2bXhhL3hZUWpONGVxQ2Q0bjNZbUYvbE9aOE05Yk42UXlMVlpkeXZvK2pxd0Q2SGZSV2x5L1RRZFhFNWs0WU5vM3B5bHh1QkhBNXZnPT0tLXVGN0REdWVNdVhINWU2WWxUeVdZK3c9PQ%3D%3D--31fcb4b3c33970f194f2f6d81beb509a47ba0b0d")
	req.AddCookie(&http.Cookie{Name: "_ga",Value: "GA1.2.1084946596.1625314918"})
	req.AddCookie(&http.Cookie{Name: "jsj_uid",Value: "bbb0a6ef-d2ad-4f91-b46b-eb817318130e"})
	req.AddCookie(&http.Cookie{Name: "my_forms_has_data",Value: "true"})

	req.AddCookie(&http.Cookie{Name: "start_filling_time_GBXkNY",Value:strconv.FormatInt( tt.Unix(),10) })
	req.AddCookie(&http.Cookie{Name: "filled_form_scene",Value: "form"})
	req.AddCookie(&http.Cookie{Name: "referer_url",Value: "https%3A%2F%2Fjinshuju.net%2Ff%2FkDiOo6"})
	req.AddCookie(&http.Cookie{Name: "locale",Value: "zh-CN"})
	req.AddCookie(&http.Cookie{Name: "start_filling_time_kDiOo6",Value: strconv.FormatInt( t.Unix(),10)})

	req.Header.Set("origin", "https://jinshuju.net")
	req.Header.Set("referer", "https://jinshuju.net/f/kDiOo6")
	req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Windows"`)
	req.Header.Set("sec-fetch-dest", "empty")
	req.Header.Set("sec-fetch-mode", "cors")
	req.Header.Set("sec-fetch-site", "same-origin")
	req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36")
	req.Header.Set("x-gd-ssf", "MTY1MzU2MDE2Ng==--346c02ec24b94e814ca10ccea5018d40926b1a26")
	req.Header.Set("x-jsj-cps", "eyJfcmFpbHMiOnsibWVzc2FnZSI6Ild5SjBTM1ppY2xWWlRpSXNJamxrYVZkMU4wMU9JaXdpUWxOUmEyY3haRWtpTENKWGNYbExibEJVV1NKZCIsImV4cCI6IjIwMjItMDYtMjZUMTA6MTY6MDYuMDczWiIsInB1ciI6bnVsbH19--a1c9af4a071f40e71cf41d3850075cbd8b035874")

	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	strBody:=string(bodyText)
	if ok:=strings.Contains(strBody, "success");ok {
		log.Println("打卡成功！")
		SendMail(config,"恭喜打卡成功!","今日打卡成功通知")
	}else {
		log.Println(strBody)
		log.Println("打卡失败！")
		SendMail(config,"打卡失败!","今日打卡失败通知")
	}

}